#ifndef _SCIFIFO_H_
#define _SCIFIFO_H_

#include "swp_incl.h"

/**
 * @file scififo.h
 * @author calm
 * @brief scififo
 * @version 1.1
 * 	scififo_at 修改，从out开始读起
 * @date 2023-03-03
 *  
 * @copyright Copyright (c) 2023
 * 
 */

struct scififo_t {
	unsigned int	in;
	unsigned int	out;
	unsigned int	mask;
	uint8_t        *data;    
};

#define DECLARE_SCIFIFO(fifo, size) struct { \
    struct scififo_t scififo; \
    uint8_t buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \
} fifo

#define INIT_SCIFIFO(fifo) { \
    typeof(&fifo) _tmp = &fifo; \
    struct scififo_t *_scififo = &_tmp->scififo; \
    _scififo->in = 0; \
    _scififo->out = 0; \
    _scififo->mask = sizeof(_tmp->buf) / sizeof(_tmp->buf[0]) - 1; \
    _scififo->data = _tmp->buf; \
}

#define scififo_clear(fifo)  _scififo_clear((struct scififo_t *)fifo)
#define scififo_at(fifo, n) _scififo_at((struct scififo_t *)fifo, n)
#define scififo_append(fifo, c) _scififo_append((struct scififo_t *)fifo, c)
#define scififo_length(fifo) _scififo_length((struct scififo_t *)fifo)
#define scififo_copy(fifo, des, len) _scififo_copy((struct scififo_t *)fifo, des, len)
#define scififo_remove(fifo, n) _scififo_remove((struct scififo_t *)fifo, n)

void _scififo_clear(struct scififo_t *);
void _scififo_append(struct scififo_t *, uint8_t c);
uint8_t  _scififo_at(struct scififo_t *, uint16_t n);
uint16_t _scififo_length(struct scififo_t *);
uint16_t _scififo_copy(struct scififo_t *, void *des, uint16_t len);
uint16_t _scififo_remove(struct scififo_t *, uint16_t n);

#endif /* _SCIFIFO_H_ */
